#ifndef WENZ_MODEL_H
#define WENZ_MODEL_H

#include <vector>
#include <map>
#include <string>
#include <cmath>
#include "common_type.h"
#include "DataFrame.h"

namespace AlgoEnvNoise {

/**
 * @brief 噪声源类型枚举
 */
enum class NoiseSourceType {
    WIND,           // 风浪噪声
    RAIN,           // 雨噪声
    SHIPPING,       // 船舶噪声
    THERMAL,        // 热噪声
    BIOLOGICAL      // 生物噪声
};

/**
 * @brief 船舶噪声等级枚举
 */
enum class ShippingLevel {
    LEVEL_0 = 0,    // 等级0：极低密度航运
    LEVEL_1 = 1,    // 等级1：低密度航运
    LEVEL_2 = 2,    // 等级2：中低密度航运
    LEVEL_3 = 3,    // 等级3：中高密度航运
    LEVEL_4 = 4     // 等级4：高密度航运
};

/**
 * @brief 环境参数结构
 */
struct EnvironmentalParameters {
    double temperature;     // 水温 (°C)
    double salinity;        // 盐度 (ppt)
    double depth;          // 水深 (m)
    double pressure;       // 压力 (Pa)
    
    EnvironmentalParameters(double temp = 15.0, double sal = 35.0, 
                          double d = 100.0, double p = 101325.0)
        : temperature(temp), salinity(sal), depth(d), pressure(p) {}
};

/**
 * @brief 频率范围结构
 */
struct FrequencyRange {
    double min_freq;        // 最小频率 (Hz)
    double max_freq;        // 最大频率 (Hz)
    size_t num_points;      // 频率点数
    bool log_scale;         // 是否使用对数刻度
    
    FrequencyRange(double min_f = 1.0, double max_f = 100000.0, 
                  size_t num = 1000, bool log = true)
        : min_freq(min_f), max_freq(max_f), num_points(num), log_scale(log) {}
    
    /**
     * @brief 生成频率序列
     * @return 频率向量
     */
    std::vector<double> generateFrequencies() const;
};

/**
 * @brief 噪声谱密度结果结构
 */
struct NoiseSpectrum {
    std::vector<double> frequencies;    // 频率 (Hz)
    std::vector<double> levels;         // 谱密度级 (dB re 1 μPa²/Hz)
    NoiseSourceType source_type;       // 噪声源类型
    std::string description;           // 描述信息
    
    NoiseSpectrum() : source_type(NoiseSourceType::WIND) {}
    
    /**
     * @brief 获取指定频率的噪声级
     * @param frequency 频率 (Hz)
     * @return 噪声级 (dB re 1 μPa²/Hz)
     */
    double getNoiseLevel(double frequency) const;
    
    /**
     * @brief 计算频带内的总噪声级
     * @param freq_band 频带范围 [min_freq, max_freq]
     * @return 总噪声级 (dB re 1 μPa)
     */
    double getTotalLevel(const std::pair<double, double>& freq_band) const;
};

/**
 * @brief WENZ模型核心类
 * 
 * 实现基于Wenz模型的海洋环境噪声计算
 */
class WenzModel {
private:
    EnvironmentalParameters env_params_;
    std::map<ShippingLevel, double> shipping_noise_levels_;
    
    // 模型参数
    static constexpr double WIND_COEFFICIENT = 50.0;      // 风噪声系数
    static constexpr double RAIN_COEFFICIENT = 35.0;      // 雨噪声系数
    static constexpr double THERMAL_COEFFICIENT = -15.0;  // 热噪声系数
    
public:
    /**
     * @brief 构造函数
     * @param env_params 环境参数
     */
    explicit WenzModel(const EnvironmentalParameters& env_params = EnvironmentalParameters());
    
    /**
     * @brief 析构函数
     */
    ~WenzModel() = default;
    
    /**
     * @brief 设置环境参数
     * @param env_params 环境参数
     */
    void setEnvironmentalParameters(const EnvironmentalParameters& env_params);
    
    /**
     * @brief 设置船舶噪声等级
     * @param level 船舶等级
     * @param noise_level 噪声级 (dB re 1 μPa²/Hz at 1kHz)
     */
    void setShippingLevel(ShippingLevel level, double noise_level);
    
    /**
     * @brief 计算风浪噪声谱
     * @param wind_speed 风速 (m/s)
     * @param freq_range 频率范围
     * @return 风浪噪声谱
     */
    NoiseSpectrum calculateWindNoise(double wind_speed, const FrequencyRange& freq_range) const;
    
    /**
     * @brief 计算雨噪声谱
     * @param rain_rate 雨量率 (mm/h)
     * @param freq_range 频率范围
     * @return 雨噪声谱
     */
    NoiseSpectrum calculateRainNoise(double rain_rate, const FrequencyRange& freq_range) const;
    
    /**
     * @brief 计算船舶噪声谱
     * @param shipping_level 船舶等级
     * @param freq_range 频率范围
     * @return 船舶噪声谱
     */
    NoiseSpectrum calculateShippingNoise(ShippingLevel shipping_level, 
                                       const FrequencyRange& freq_range) const;
    
    /**
     * @brief 计算热噪声谱
     * @param freq_range 频率范围
     * @return 热噪声谱
     */
    NoiseSpectrum calculateThermalNoise(const FrequencyRange& freq_range) const;
    
    /**
     * @brief 计算总体环境噪声谱
     * @param wind_speed 风速 (m/s)
     * @param rain_rate 雨量率 (mm/h)
     * @param shipping_level 船舶等级
     * @param freq_range 频率范围
     * @return 总体环境噪声谱
     */
    NoiseSpectrum calculateTotalNoise(double wind_speed, double rain_rate,
                                    ShippingLevel shipping_level,
                                    const FrequencyRange& freq_range) const;
    
    /**
     * @brief 使用环境数据计算时空变化的噪声场
     * @param coord 时空坐标
     * @param shipping_level 船舶等级
     * @param freq_range 频率范围
     * @return 环境噪声谱
     */
    NoiseSpectrum calculateEnvironmentalNoise(const EnvData::SpatioTemporalCoord& coord,
                                            ShippingLevel shipping_level,
                                            const FrequencyRange& freq_range) const;
    
    /**
     * @brief 合并多个噪声谱
     * @param spectra 噪声谱向量
     * @return 合并后的噪声谱
     */
    static NoiseSpectrum combineSpectra(const std::vector<NoiseSpectrum>& spectra);
    
    /**
     * @brief 噪声谱插值
     * @param spectrum 噪声谱
     * @param target_frequencies 目标频率序列
     * @return 插值后的噪声谱
     */
    static NoiseSpectrum interpolateSpectrum(const NoiseSpectrum& spectrum,
                                           const std::vector<double>& target_frequencies);
    
    /**
     * @brief 获取当前环境参数
     * @return 环境参数
     */
    const EnvironmentalParameters& getEnvironmentalParameters() const { return env_params_; }
    
private:
    /**
     * @brief 计算风浪噪声谱密度
     * @param wind_speed 风速 (m/s)
     * @param frequency 频率 (Hz)
     * @return 噪声谱密度 (dB re 1 μPa²/Hz)
     */
    double calculateWindNoiseLevel(double wind_speed, double frequency) const;
    
    /**
     * @brief 计算雨噪声谱密度
     * @param rain_rate 雨量率 (mm/h)
     * @param frequency 频率 (Hz)
     * @return 噪声谱密度 (dB re 1 μPa²/Hz)
     */
    double calculateRainNoiseLevel(double rain_rate, double frequency) const;
    
    /**
     * @brief 计算船舶噪声谱密度
     * @param shipping_level 船舶等级
     * @param frequency 频率 (Hz)
     * @return 噪声谱密度 (dB re 1 μPa²/Hz)
     */
    double calculateShippingNoiseLevel(ShippingLevel shipping_level, double frequency) const;
    
    /**
     * @brief 计算热噪声谱密度
     * @param frequency 频率 (Hz)
     * @return 噪声谱密度 (dB re 1 μPa²/Hz)
     */
    double calculateThermalNoiseLevel(double frequency) const;
    
    /**
     * @brief 频率修正因子
     * @param frequency 频率 (Hz)
     * @return 修正因子
     */
    double getFrequencyCorrection(double frequency) const;
    
    /**
     * @brief 深度修正因子
     * @param depth 深度 (m)
     * @param frequency 频率 (Hz)
     * @return 修正因子
     */
    double getDepthCorrection(double depth, double frequency) const;
    
    /**
     * @brief 初始化船舶噪声等级
     */
    void initializeShippingLevels();
};

/**
 * @brief 环境噪声计算器类
 * 
 * 高级接口，结合环境数据进行噪声计算
 */
class EnvironmentalNoiseCalculator {
private:
    WenzModel wenz_model_;
    std::shared_ptr<EnvData::EnvironmentalDataManager> data_manager_;
    
public:
    /**
     * @brief 构造函数
     * @param env_params 环境参数
     */
    explicit EnvironmentalNoiseCalculator(const EnvironmentalParameters& env_params = EnvironmentalParameters());
    
    /**
     * @brief 计算指定区域和时间的噪声分布
     * @param time_range 时间范围
     * @param lat_range 纬度范围
     * @param lon_range 经度范围
     * @param shipping_level 船舶等级
     * @param freq_range 频率范围
     * @return 噪声谱向量
     */
    std::vector<NoiseSpectrum> calculateRegionalNoise(
        const std::pair<double, double>& time_range,
        const std::pair<double, double>& lat_range,
        const std::pair<double, double>& lon_range,
        ShippingLevel shipping_level,
        const FrequencyRange& freq_range) const;
    
    /**
     * @brief 计算时间序列噪声
     * @param latitude 纬度
     * @param longitude 经度
     * @param time_points 时间点序列
     * @param shipping_level 船舶等级
     * @param freq_range 频率范围
     * @return 时间序列噪声谱
     */
    std::vector<NoiseSpectrum> calculateTimeSeriesNoise(
        double latitude, double longitude,
        const std::vector<double>& time_points,
        ShippingLevel shipping_level,
        const FrequencyRange& freq_range) const;
    
    /**
     * @brief 导出噪声计算结果
     * @param filename 文件名
     * @param spectra 噪声谱向量
     * @return 是否导出成功
     */
    bool exportResults(const std::string& filename, const std::vector<NoiseSpectrum>& spectra) const;
    
    /**
     * @brief 获取WENZ模型引用
     * @return WENZ模型引用
     */
    WenzModel& getWenzModel() { return wenz_model_; }
};

} // namespace AlgoEnvNoise

#endif // WENZ_MODEL_H 